package com.hn.zhijian.web.config.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

/**
 * @program: carl-main
 * @description: JWT工具类
 * @author: carl
 * @create: 2019-12-09 23:09
 **/
@Configuration
@ConfigurationProperties(prefix = "shiro-jwt")
@Data
public class JwtExecute {
    /**
     * token 失效时间
     */
    private Long expireTime;

    /**
     * 秘钥
     */
    private String secret;

    /**
     * 时间过期单位
     */
    private String timeUnit = TimeUnit.MM.name();

    /**
     * 校验token是否正确
     *
     * @param token 密钥
     * @return 是否正确
     */
    public boolean verify(String token, String username) {
        try {
            //根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(createSecretKey().getAlgorithm());
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("username", username)
                    .build();
            //效验TOKEN
            DecodedJWT jwt = verifier.verify(token);
        } catch (TokenExpiredException tokenExpiredException) {
            System.out.println("token 过期");
            //token时间过期
            return false;
        } catch (Exception exception) {
            //验证失败
            return false;
        }

        return true;
    }


    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名,5min后过期
     *
     * @param username 用户名
     * @return 加密的token
     */
    public String sign(String username) {
        Date date = new Date(System.currentTimeMillis() + getDateLong());
        Algorithm algorithm = Algorithm.HMAC256(createSecretKey().getAlgorithm());
        // 附带username信息
        return JWT.create()
                .withClaim("username", username)
                .withExpiresAt(date)
                .withIssuedAt(new Date())
                .sign(algorithm);
    }


//    public static void main(String[] args) {
//        Long time = (60 * 60)* 24 * 1000L;
//        System.out.println(time);
//        Date date = new Date(System.currentTimeMillis() + time);
//        System.out.println(DateUtils.format(date));
//        System.out.println(TimeUnit.DD.name());
//    }

    /**
     * 生成秘钥
     *
     * @return
     */
    private SecretKey createSecretKey() {
        //本地的密码解码
        byte[] encodedKey = Base64.decodeBase64(secret);
        //生成秘钥
        SecretKey secretKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return secretKey;
    }

    private Long getDateLong(){
        if(timeUnit.toLowerCase().equals(TimeUnit.DD.name().toLowerCase())){
            //按天
            return  (60*60*24*1000L) * expireTime;
        }else if(timeUnit.toLowerCase().equals(TimeUnit.HH.name().toLowerCase())){
            //小时
            return (60 * 60 * 1000L) * expireTime;
        }else if(timeUnit.toLowerCase().equals(TimeUnit.SS.name().toLowerCase())){
            //秒
            return expireTime * 1000L;
        }else{
            //分
            return  (60 * 1000L) * expireTime;
        }
    }
}
